כשאני בונה צאט ב jq ajax אני משתמש ב settimeout כדי לרענן את הפונקציה ששולפת בעזרת POST את הדף עם הצגת ההודעות.
עכשיו, אני יודע שזה לא יעיל מכוון שאם יש לי המון משתמשים בצאט, ואצל כל אחד הצאט מתרענן כל שנייה, זה יעמיס על השרת.
השאלה שלי איך אפשר לעשות שהצאט יתרענן אך ורק אם יש הודעה חדשה? כדי שיעמיס פחות על השרת?
תודה רבה!
11 תשובות
גם אם זה אפשרי, אני לא בטוח שזה יהיה יעיל כל-כך, בכל מקרה תצטרך לרענן את פונקציית הבדיקה...
אפשר לבצע long polling.
iiddaannyy, אפשר הסבר מה זה?
ואיך אתרים גדולים של צאטים עושים את זה? הם מרעננים כל שנייה? לא נראה לי.
long polling היא פשוט request ארוך לשרת. הדפדפן שולח לשרת בקשה -> השרת בודק האם יש משהו חדש במסד.
כל עוד אין משהו חדש במסד הוא לא מחזיר תשובה.
ברגע שיש משהו חדש במסד הוא מחזיר תשובה לדפדפן וככה הדפדפן יודע שהתקבלה הודעה חדשה לדוגמה.
לחלופין, אפשר לעבוד עם node.js בצורה הזו (אני מאוד חדש בקטע של node.js, ככה שיכול להיות שאני מדבר שטויות עכשיו):
var sockets = [];
var chat = net.Server(function(socket) {
sockets.push(socket);
socket.on('data', function(data) {
for (var i=0; i < sockets.length; i++) {
if (sockets[i] != socket) {
sockets[i].write(data);
}
}
});
socket.on('end', function() {
sockets.splice(sockets.indexOf(socket), 1);
});
});
chat.listen('100'); // 100 is your port
הבאתי דוגמה עם node.
node זו לא האופציה היחידה.
בעקרון אתה צריך להשתמש בWEBSOCKET של HTML5, מה שזה עושה, זה משאיר חיבור קבוע בינך לבין השרת
ואם לשרת יש משהו חדש לעדכן הוא זה ששולח לך ולא אתה מתשאל אותו...
אני יודע שהצ'ט של פייסבוק עובד על זה...
אבל זו שיטה ממש חדשה ולא נתמכת בכל הדפדפנים...
האמת היא שראיתי פתרון נחמד לזה. את כל העניין של פתיחת הסוקטים והכל מבצעים בשרת.
(מאזינים להתחברויותבפורט מסוים, ואז שולחים סוקט באמצעות php)
בעמוד ה-html יוצרים iframe שמקשר לקובץ שפתח את הסוקט. כשיש הודעה חדשה, הקובץ שפתח את הסוקט שולח פלט לדפדפן (הפלט יופיע ב-iframe), ואותו פלט יכלול הפעלה של פונקציה בעמוד ה-html שלנו.
משהו כזה:
function newMessage(msg) {
alert('new message: '+msg);
}
</script>
<iframe src="sockets.php"></iframe>
כל פעם שיש הודעה חדשה, sockets.php ישלח פלט חדש (שיופיע ב-iframe). דוגמה לפלט:
parent.newMessage($msg);
</script>
וכך תופעל הפונקציה newMessage כשתגיעה הודעה חדשה.
http://www.youtube.com/watch?v=69OXnmbAaLI
עידן, אני די בטוח שאם אתה עובד עם סוקטים אתה צריך לכתוב בעצמך כל פעם HEADERS לפרוטוקול HTTP, אם אתה רוצה שזה יתפקד דרך הAJAX.(דיברתי על הnode)
האמת היא שהחלטתי לקחת יוזמה ולנסות לבנות מן שרת סוקטים קטן (אין לי מושג בכל העניין של סוקטים, ככה שזה טוב להתחלה).
הנה שרת סוקטים (אם זה בסדר לקרוא לזה כך, לא יודע) שמאזין לפורט 100.
http://pastebin.com/jBRbPvpB
תמונה של זה עובד (תמונה גדולה, מצטער):
http://ufu.co.il/files/se3whjuwkuvlwi6nxthl.png
סדר הפעולות בתמונה:
1. מפעילים את השרת (את ההאזנה לפורט 100) על ידי הרצת הקובץ.
2. שלושה מתחברים לשרת.
3. קליינט ראשון בוחר את השם Idan.
4. קליינט שני את intval.
5. קליינט שלישי את questioner.
6. Idan שולח הודעה.
7. intval שולח הודעה.
8. questioner שולח הודעה.
9. Idan סוגר את החיבור שלו לשרת (ctrl+c עושה את זה בלינוקס. אם אני לא טועה אז גם במאק).
10. intval סוגר את החיבור.
11. questioner סוגר את החיבור.
12. סגירה של השרת.